/*******************************************************************************
 * Copyright (c) 2007, Geophysical Center RAS
 * Sergey Berezin, Dmitry Voitsekhovskiy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Geophysical Center RAS nor the names
 * of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace VisualEsse.DataEngine.Types {

	/// <summary>
	/// The two-component floating point vector
	/// </summary>
	public struct double2 {

		public double2(double fx, double fy) {
			this.fx = fx;
			this.fy = fy;
		}  // end of double2()

		public double2(double fx) : this(fx, fx) {}

		public static double2 operator +(double2 a, double2 b) {
			return new double2(a.fx + b.fx, a.fy + b.fy);
		}  // end of operator+()

		public static double2 operator +(double2 a, double b) {
			return a + new double2(b);
		}  // end of operator+()

		public static double2 operator +(double a, double2 b) {
			return new double2(a) + b;
		}  // end of operator+()

		public static double2 operator -(double2 a, double2 b) {
			return new double2(a.fx - b.fx, a.fy - b.fy);
		}  // end of operator-()

		public static double2 operator -(double2 a, double b) {
			return a - new double2(b);
		}  // end of operator-()

		public static double2 operator -(double b, double2 a) {
			return new double2(b) - a;
		}  // end of operator-()

		public static double2 operator -(double2 a) {
			return new double2(-a.fx, -a.fy);
		}  // end of operator-()

		public static double2 operator *(double2 a, double2 b) {
			return new double2(a.fx * b.fx, a.fy * b.fy);
		}  // end of operator*()

		public static double2 operator *(double2 a, double b) {
			return a * new double2(b);
		}  // end of operator*()

		public static double2 operator *(double a, double2 b) {
			return new double2(a) * b;
		}  // end of operator*()

		public static double2 operator /(double2 a, double2 b) {
			return new double2(a.fx / b.fx, a.fy / b.fy);
		}  // end of operator/()

		public static double2 operator /(double2 a, double b) {
			return a / new double2(b);
		}  // end of operator/()

		public static double2 operator /(double a, double2 b) {
			return new double2(a) / b;
		}  // end of operator/()

		public static explicit operator double2(double a) {
			return new double2(a, a);
		}  // end of operator double2()

/*		public static explicit operator int2(double2 a) {
			return new int2((int)a.x, (int)a.y);
		}  // end of operator int2()*/

		public static implicit operator double(double2 a) {
			return a.x;
		}  // end of operator double()

		public double x {
			get {
				return fx;
			}
			set {
				fx = value;
			}
		}  // end of x

		public double y {
			get {
				return fy;
			}
			set {
				fy = value;
			}
		}  // end of y

		public double2 xx {
			get {
				return new double2(fx);
			}
		}  // end of xx

		public double2 yy {
			get {
				return new double2(fy);
			}
		}  // end of yy

		public double2 xy {
			get {
				return this;
			}
			set {
				fx = value.fx;
				fy = value.fy;
			}
		}  // end of xy

		public double2 yx {
			get {
				return new double2(fy, fx);
			}
			set {
				fx = value.fy;
				fy = value.fx;
			}
		}  // end of yx

		public double r {
			get {
				return fx;
			}
			set {
				fx = value;
			}
		}  // end of r

		public double g {
			get {
				return fy;
			}
			set {
				fy = value;
			}
		}  // end of g

        public static double2 Max(double2 a, double2 b)
        {
            return new double2(Math.Max(a.x, b.x), Math.Max(a.y, b.y));
        }

        public static double2 Min(double2 a, double2 b)
        {
            return new double2(Math.Min(a.x, b.x), Math.Min(a.y, b.y));
        }


		/// <summary>
		/// The elements of the vector
		/// </summary>
		private double fx, fy;

	}  // end of struct double2

}  